package com.bigfans.systemservice.api;

import com.bigfans.Constants;
import com.bigfans.framework.CurrentUser;
import com.bigfans.framework.SessionUserFactory;
import com.bigfans.framework.exception.UserExistsException;
import com.bigfans.framework.exception.UserUnAuthorizedException;
import com.bigfans.framework.kafka.KafkaTemplate;
import com.bigfans.framework.utils.JsonUtils;
import com.bigfans.framework.utils.JwtUtils;
import com.bigfans.framework.web.*;
import com.bigfans.systemservice.model.Role;
import com.bigfans.systemservice.model.User;
import com.bigfans.systemservice.service.RoleService;
import com.bigfans.systemservice.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
public class UserApi extends BaseController{

    @Autowired
    private UserService userService;
    @Autowired
    private RoleService roleService;

    /**
     * 执行登录请求
     *
     * @param user
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public RestResponse login(@RequestBody User user) throws Exception {
        User loginUser = userService.login(user.getUsername(), user.getPassword());
        if (loginUser == null) {
            throw new UserUnAuthorizedException();
        }
        List<Role> myRoles = roleService.listRolesByUser(loginUser.getId());
        CurrentUser currentUser = this.createSessionUser(user , myRoles);
        String token = this.generateToken(JsonUtils.toJsonString(currentUser));
        return RestResponse.ok(token);
    }

    /**
     * 执行退出请求
     *
     * @return RestResponse
     */
    @RequestMapping(value = "/logout", method = RequestMethod.GET)
    public RestResponse logout() {
        getRequest().getSession().invalidate();
        Cookie userCookie = CookieHolder.get(Constants.TOKEN.KEY_NAME);
        if(userCookie != null){
            userCookie.setMaxAge(0);
            userCookie.setPath("/");
        }
        return RestResponse.ok();
    }

    /**
     * 执行注册请求
     *
     * @param userExample
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/register", method = RequestMethod.POST)
    public RestResponse register(User userExample) throws Exception {
        boolean passed = true;
        // 判断用户是否存在
        if (userService.accountExist(userExample.getUsername())) {
            throw new UserExistsException();
        }
        User user = userService.regist(userExample);
        List<Role> myRoles = roleService.listRolesByUser(user.getId());
        CurrentUser currentUser = this.createSessionUser(user , myRoles);
        String token = this.generateToken(JsonUtils.toJsonString(currentUser));
        return RestResponse.ok(token);
    }

    private CurrentUser createSessionUser(User user , List<Role> roles){
        Map<String , Object> claims = new HashMap<>();
        claims.put("account" , user.getUsername());
        claims.put("nickname" , user.getNickname());
        claims.put("ip" , RequestHolder.getRemoteIP());
        claims.put("loginTime" , new Date());
        claims.put("uid" , user.getId());
        claims.put("loggedIn" , true);
        claims.put("roles" , roles.stream().map(Role::getName).collect(Collectors.toList()).toArray());
        CurrentUser currentUser = SessionUserFactory.createSessionUser(claims);
        return currentUser;
    }

    private String generateToken(String tokenStr){
        String jwtTokenStr = JwtUtils.create(tokenStr, "bigfans");
        return jwtTokenStr;
    }
}
